/**
 * \file
 */
#ifndef kfs_file_descriptor_hpp_included
#define kfs_file_descriptor_hpp_included

#include "kfs.hpp"
#include <stdint.h>

class CacheRef;

class FileDescriptor
{
public:

    FileDescriptor(kfs* fs, int flags);

    ~FileDescriptor();

    /**
     * When a file is opened, the flags from fi->flags control the behaviour.
     */
    int flags;

    /** Filesystem
     */
    kfs* const fs;

    /**
     * A reference to the inode. When this descriptor is closed the reference
     * is automatically invalidated. When the inode has no more references it
     * may be ejected from the cache.
     */
    boost::scoped_ptr<CacheRef> inodeRef;

    void chmod(mode_t mode);

    void chown(uid_t uid, gid_t gid);

    void close();

    void getattr(struct stat* const mystat)
    const;

    /**
     * Read no more than maxNumBytes from the file. The operation begins at
     * the position specified by the number of bytes from the start of the
     * file.
     *
     * The number of bytes read is less than maxNumBytes if the end of file is
     * encountered.
     *
     * @param destination A buffer into which the data are copied
     * @param maxNumBytes The buffer must have at least this many bytes.
     * @return Number of bytes read
     *
     */
    size_t read(void* destination, size_t maxNumBytes,
        file_size_t filePosition)
    const;

    /**
     * Alter the size of the file.  Add or remove data at the end.  When the
     * size increases, zero bytes are used.
     */
    void truncate(file_size_t newSize);

    /**
     * Write maxNumBytes bytes to the file specified by a CacheInode. If any
     * problem occurs, write no bytes.
     *
     * @return maxNumBytes if success, and zero if failure.
     */
    size_t write(void const* source, size_t numBytes, file_size_t filePosition);
};

#endif // kfs_file_descriptor_hpp_included
